// pages/task/task.js
const app = getApp();

Component({
  /**
   * 页面的初始数据
   */
  data: {
    daily_idea: false,
    titleHeight: 90, // 象限标题高度
    viewHeight: 110, // movable-view高度
    bottomMargin: 30,
    areaHeight: 0, // movable-area高度
    tasks: {},
    _tasks: {} // 备份任务对象
  },

  methods: {
    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function (options) {
      this.setData({
        tasks: app.globalData.daily,
        daily_idea: app.globalData.operateLead.daily_idea
      });
      this.initTasks();
    },
    onShow () {
      let task = wx.getStorageSync('create-daily');
      const transferToDailyData = app.globalData.transferToDailyData;

      if (task || transferToDailyData) {
        task = transferToDailyData || JSON.parse(task);

        // daily复用了tasks的代码，保留了priority_1任务作为数据对象
        // 这里需要把所有传递过来的任务所属象限转成priority_1
        task.belong = 'priority_1';
        const list = this.data.tasks['priority_1'].list.concat([task]);
        const key = `tasks.priority_1.list`;
        this.setData({
          [key]: list
        });
        
        // 刷新页面
        this.initTasks();
        // 清除任务缓存
        wx.removeStorageSync('create-daily');
        app.globalData.transferToDailyData = undefined;
      }
    },

    /**
     * 初始化tasks对象：
     * 计算movable-area高度
     * 计算每个象限模块的高度
     * 计算每个movable-view的x,y的位置
     */
    initTasks () {
      // title和bottom-margin形成的固定高度
      const fixedHeight = this.data.titleHeight + 10;
      const tasks = this.data.tasks;
      // movable-view累加的内容高度
      let contentHeight = 0; 
      // 象限模块的高度
      let priorityModelHeight = 0;
      // 坐标累加器，用于设置movable-view的position
      let position = 0;

      for (let key in tasks) {
        const task = tasks[key];
        const list = task.list;

        priorityModelHeight = 0;
        position += this.data.titleHeight;

        list.map((view, index) => {
          contentHeight += this.data.viewHeight;
          priorityModelHeight += this.data.viewHeight;
          // 设置view的position
          const yProperty = `tasks.${key}.list[${index}].y`;
          this.setData({
            [yProperty]: position
          });
          position += this.data.viewHeight;
        });

        // 设置象限高度
        const heightProperty = `tasks.${key}.height`;
        this.setData({
          [heightProperty]: priorityModelHeight
        });

        position += this.data.bottomMargin;
      }

      this.setData({
        areaHeight: fixedHeight + contentHeight
      });
    },

    /**
     * 长按释放移动:
     * 为了用户体验，默认是不允许移动任务的
     * 需要用户长按任务项后才能移动
     * 
     * @param {*} e 
     */
    handleLongPress (e) {
      wx.vibrateShort({
        type: 'heavy'
      });
      this.setViewMovable(e.currentTarget.dataset, false);
    },

    // 重置相关数据
    bindtouchstart (e) {
      this.setData({
        _tasks: {}
      });
    },

    /**
     * 在拖动过程中计算被拖动的view坐标处于 任务队列的哪里
     * 然后再插入到对应的位置
     * 
     * @param {*} e 
     */
    handleMoveChange (e) {
      // 防抖
      const changeCancel = this.data.changeCancel;
      if (changeCancel) {
        clearTimeout(changeCancel);
        this.setData({
          changeCancel: null
        });
      }

      const action = setTimeout(() => {
        let { y } = e.detail; // 单位是 px
        y = app.methods.pxToRpx(y); // 转换成 rpx
        const { y: viewY, id, task, viewIndex } = e.currentTarget.dataset; // 单位是 rpx
        const tasks = this.data.tasks;

        if (y === viewY) {
          return;
        }

        /**
         * 1.
         * 如果移动viewA的中线处于任务象限的标题内时，则将viewA移动到该象限内的首位
         * 
         * 2.
         * 获取移动viewA的中线Y坐标，如果Y坐标位于其他的 viewB 内，则做如下判断：
         * 如果viewA的中线在viewB的Y坐标范围之外，则移动失败
         * 如果viewA的中线在viewB的中线的上半部分中，则顺序为：viewB,viewA
         * 如果viewA的中线在viewB的中线下半部分中，则顺序为：viewA,viewB
         * 如果中线重叠时；viewA的位置>viewB时则顺序为: viewA,viewB，否则为：viewB,viewA
         * 
         * 其他情况则移动失败
         */
        const middleLine = this.data.viewHeight / 2;
        const baseLine = y + middleLine; // 移动view的中线Y坐标
        let currentView = null;
        let transferView = null;
        let order = 0; // -1:向上移动；1:向下移动 
        let titleY = 0; // 象限标题的坐标
        let isTitlePosition = false; // 是否停留在title位置
        const _tasks = {}; // 内部暂存数据
        
        for (let property in tasks) {
          const list = tasks[property].list || [];

          // 是否在象限标题内
          if (baseLine >= titleY && baseLine <= titleY + this.data.titleHeight) {
            transferView = list[0] || {belong: property}; // 象限中任务可能会为空
            order = -1;
            isTitlePosition = true;
          }

          titleY += this.data.titleHeight;

          // 是否在其他view内
          list.map((item, index) => {
            titleY += this.data.viewHeight;

            if (item.id === id) {
              // currentView只是浅拷贝，会导致问题
              currentView = JSON.parse(JSON.stringify(item));
              return;
            };
            const startY = item.y;
            const middleY = item.y + middleLine;
            const endY = item.y + this.data.viewHeight;

            if (baseLine >= startY && baseLine <= middleY) {
              console.log('view进入上半部分，准备移动到后面！');
              transferView = item;
              order = 1;
            }
            if (baseLine <= endY && baseLine > middleY) {
              console.log('view进入下半部分，准备移动到前面！');
              transferView = item;
              order = -1;
            }
            // 暂时不考虑边界问题
            // if (baseLine === middleLine) {
            //   console.log('view重合了，准备按位置移动！');
            // }
          });

          titleY += this.data.bottomMargin;
        }
     
        // 在范围内，准备移动 
        if (transferView && order !== 0) {
          // 将移动的viewA从原来的位置移除
          const { belong: cBelong, id: cId } = currentView;
          _tasks[cBelong] = {list: []};
          for (let item of tasks[cBelong].list) {
            if (item.id !== cId) {
              _tasks[cBelong].list.push(item);
            }
          }

          // 定位到viewB的位置，然后根据order，将viewA插入到前面或者后面
          const { belong: tBelong, id: tId } = transferView;
          const list = [];
          _tasks[tBelong] = {list: []};
          currentView.belong = tBelong;

          if (tId) { // 象限中有数据时
            for (let item of tasks[tBelong].list) {
              if (item.id === cId) { // 同一个象限内移动时
                // 放止移动到标题位置时，导致多次添加
                (isTitlePosition && cId === tId) ? list.push(item) : '';
                continue;
              } else if (item.id === tId) {
                // 向后插入
                if (order === 1) {
                  list.push(item, currentView);
                }
                // 向前插入
                if (order === -1) {
                  list.push(currentView, item);
                }
                continue;
              } else {
                list.push(item);
              }
            }
          } else { // 象限中无数据时，直接赋值
            list.push(currentView);
          }

          _tasks[tBelong].list = list;
        }

        this.setData({
          _tasks
        });
  
      }, 50);
      this.setData({
        changeCancel: action
      });
    },

    /**
     * 将对应的movable-view设置为不可移动
     *
     * @param {*} e 
     */
     handleTouchend (e) {
      const _tasks = this.data._tasks;
      for (let property in _tasks) {
        const key = `tasks.${property}.list`;
        this.setData({
          [key]: _tasks[property].list
        });
      }
      this.initTasks();

      // 注意this.setData，数据是同步更新的，但视图是异步变化更新的
      // 将movable-view设置为不可移动
      setTimeout(() => {
        this.setViewMovable(e.currentTarget.dataset, true);
      }, 800);
    },

    setViewMovable (dataset, disable) {
      const { id } = dataset;
      let key = '';

      for (let priority in this.data.tasks) {
        const list = this.data.tasks[priority].list;
        list.map((item, index) => {
          if (item.id === id) {
            key = `tasks.${priority}.list[${index}].disable`;
          }
        });
      }

      this.setData({
        [key]: disable
      });
    },

    toCreatePage () {
      wx.vibrateShort({
        type: 'heavy'
      });
      wx.navigateTo({
        url: '/pages/create-daily/create-daily',
        fail: () => {
          wx.showModal({
            title: '错误提示',
            content: '页面跳转失败！'
          });
        }
      });
    },

    handleDeleteTask (e) {
      const { belong, id } = e.detail;
      const list = [];
      const key = `tasks.${belong}.list`;

      for (let item of this.data.tasks[belong].list) {
        if (item.id !== id) {
          list.push(item);
        }
      }

      this.setData({
        [key]: list
      });
      this.initTasks();
    },

    actionTask (e) {
      const { info } = e.detail;

      app && app.globalData 
      ?
      app.globalData.transferToClockData = info
      :
      ''

      wx.switchTab({
        url: '/pages/clock/clock',
        fail: ()=>{
          wx.showModal({
            title: '错误提示',
            content: '页面跳转失败！'
          });
        }
      });
    },

    handleCloseLead (e) {
      const key = e.currentTarget.dataset.key;

      this.setData({
        [key]: false
      });

      app.globalData.operateLead[key] = false
    }
  },

  observers: {
    'tasks.**': function (data) {
      console.log('daily list change');
      wx.setStorageSync('daily', JSON.stringify(data));
    }
  }
})